/*

Summary:
Used to convert net address to string, or contrary.

Remark:
FromString returns -1 when the argument does not contain
a legitimate Internet address. It's conflict with address 
"255.255.255.255". Therefore if the function returns -1, 
you should check whether it is a broadcast address, or just 
use the more secure version.

Version:
0.2.0

LastUpdatedDate:
2012-08-08

*/


#pragma once
#include <string>
#include <WinSock2.h>
#include "..\Encoding.h"


namespace Zaf {
namespace Net {


template<typename CharType>
std::basic_string<CharType> ToString(unsigned int inAddr);

template<>
inline std::string ToString<char>(unsigned int inAddr) {
	in_addr in;
	in.S_un.S_addr = inAddr;
	return inet_ntoa(in);
}

template<>
inline std::wstring ToString<wchar_t>(unsigned int inAddr) {
	return Zaf::Decode<Zaf::Utf8>(ToString<char>(inAddr));
}



template<typename CharType>
unsigned int FromString(const std::basic_string<CharType>& str);

template<>
inline unsigned int FromString<char>(const std::string& str) {
	return inet_addr(str.c_str());
}

template<>
inline unsigned int FromString<wchar_t>(const std::wstring& str) {
	return inet_addr(Zaf::Encode<Zaf::Utf8>(str).c_str());
}



template<typename CharType>
unsigned int FromString(const CharType* str);

template<>
inline unsigned int FromString<char>(const char* str) {
	return inet_addr(str);
}

template<>
inline unsigned int FromString<wchar_t>(const wchar_t* str) {
	return FromString(std::wstring(str));
}



template<typename CharType>
bool FromString(const std::basic_string<CharType>& str, unsigned int& addr);

template<>
inline bool FromString<char>(const std::string& str, unsigned int& addr) {
	unsigned int result = FromString(str);
	if (result == -1 && str != "255.255.255.255") {
		return false;
	}
	addr = result;
	return true;
}

template<>
inline bool FromString<wchar_t>(const std::wstring& str, unsigned int& addr) {
	unsigned int result = FromString(str);
	if (result == -1 && str != L"255.255.255.255") {
		return false;
	}
	addr = result;
	return true;
}



template<typename CharType>
bool FromString(const CharType* str, unsigned int& addr);

template<>
inline bool FromString<char>(const char* str, unsigned int& addr) {
	unsigned int result = FromString(str);
	if (result == -1 && strcmp(str, "255.255.255.255") != 0) {
		return false;
	}
	addr = result;
	return true;
}

template<>
inline bool FromString<wchar_t>(const wchar_t* str, unsigned int& addr) {
	unsigned int result = FromString(str);
	if (result == -1 && wcscmp(str, L"255.255.255.255") != 0) {
		return false;
	}
	addr = result;
	return true;
}

}
}